<!--
  下拉/级联弹出框组件              zls-2022/06/04
      切记：
          1) 在父组件中必须使用confirm函数（因为后台最重要的必然是code值，而页面上渲染的是text值）！！！！
          2) 对于select形式的级联选择器数据，最外层需要多包一层空对象（主要用于数据回选！！！！）

      Attributes
          1、allowClick      是否可以点击弹框下拉/级联框（默认为true），常用于下拉/级联框关联
          2、input公共组件的部分属性
          其他所有属性均参考vant组件库中的  "Picker 选择器"

      Events
          1、confirm        弹出框的确认按钮

      Demo==>
          请参考 Form 表单组件
-->

<template>
  <div class="z-select">
    <z-input
      :label="$attrs.label"
      :modelValue="$attrs.modelValue"
      :labelWidth="$attrs['labelWidth']"
      :placeholder="$attrs.placeholder || '请选择'"
      :svg="$attrs.svg || 'jiantou'"
      readonly
      clickable
      @click="open"
      @input="input"
    ></z-input>
    <Popup
      v-model:show="show"
      :overlay="$attrs['overlay']"
      :position="$attrs['position'] || 'bottom'"
      :lock-scroll="$attrs['lock-scroll']"
      :close-on-click-overlay="$attrs['close-on-click-overlay']"
      :closeable="$attrs['closeable']"
      :close-icon="$attrs['close-icon']"
      :close-icon-position="$attrs['close-icon-position']"
      :safe-area-inset-bottom="true"
      round
      close-on-popstate
      @click-overlay="show = false"
      @click-close-icon="show = false"
    >
      <Picker
        :columns="$attrs['columns']"
        :columns-field-names="$attrs['columns-field-names']"
        :title="$attrs['title']"
        :loading="$attrs['loading']"
        :show-toolbar="$attrs['show-toolbar'] === false ? false : true"
        :readonly="$attrs['readonly']"
        :default-index="$attrs['default-index']"
        :class="{ isCascader: isCascader }"
        @confirm="confirm"
        @cancel="show = false"
      />
    </Popup>
  </div>
</template>

<script>
export default { name: 'z-select' }
</script>
<script setup>
import { getType } from '@/utils/index'
import { ref, getCurrentInstance, inject, useAttrs } from 'vue'
import { Toast, Picker, Popup } from 'vant'
const $attrs = useAttrs()
const global = getCurrentInstance().appContext.config.globalProperties
const formItem = inject('formItem')
const emit = defineEmits(['confirm'])
const props = defineProps({
  // 是否可以点击弹框下拉/级联框（默认为true）
  allowClick: {
    type: Boolean,
    default: true
  }
})
const show = ref(false) // 是否弹出
const isCascader = ref($attrs.columns.length && $attrs.columns[0].children) // 是否是级联选择器（需要它判断逻辑和改变样式）
// 打开弹框
function open() {
  if ($attrs.columns.length) {
    if (props.allowClick) {
      show.value = true
    } else {
      show.value = false
      Toast('请先选择上级内容')
    }
  } else {
    Toast('暂无数据')
  }
}

// 选中某一项后，点击确认按钮 { value:当前项的信息，index: 当前项的索引 }
// 如果返回的值是一个对象，说明是下拉框；如果返回的值是一个数组，说明是级联框；
function confirm(value, index) {
  let params
  if (getType(value) === 'array') {
    let code = [],
      text = []
    value.forEach((v, i) => {
      if (i !== 0) {
        code.push(v.code)
        text.push(v.text)
      }
    })
    params = { code, text: text.join() }
  } else {
    params = value
  }
  show.value = false
  emit('confirm', params, index)
  global.$bus.emit('formItem-change', formItem.value.prop || 'noProp')
}

// 实时改变
function input() {
  show.value = false
  isCascader.value ? emit('confirm', { code: null, text: '' }, null) : emit('confirm', '', '')
  global.$bus.emit('formItem-change', formItem.value.prop || 'noProp')
}
</script>

<style lang="scss" scoped>
:deep(.isCascader) {
  .van-picker__columns {
    .van-picker-column:first-child {
      display: none;
    }
  }
}
</style>
